#include "server.h"
#include <QDebug>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostInfo>

bool isIPv4Address(const QHostAddress &addr)
{
    // 检查addr是否不是IPv6地址
    return addr.protocol() == QAbstractSocket::IPv4Protocol;
}

Server::Server(QObject *parent) : QTcpServer(parent)
{
    // 设置监听的端口等
    listen(QHostAddress::AnyIPv4, 7890);

    // 连接相关的信号槽
    connect(this, &Server::newConnection, this, &Server::NewClient_cb);

    // 获取本地主机信息
    QHostInfo hostInfo = QHostInfo::fromName(QHostInfo::localHostName());
    // 遍历接口的地址
    QHostAddress addr;
    foreach (addr, hostInfo.addresses())
    {
        // 检查是否是IPv4地址
        if (isIPv4Address(addr))
        {
            if (addr.toString().indexOf(".") > 0)
            {
                qDebug() << "Address:" << addr.toString();
                HostAddr = addr.toString();
            }
        }
    }
}

void Server::SendData(QByteArray data)
{
    // 遍历客户端列表，将数据发送到所有客户端中（类似广播）
    //    if(this->hasPendingConnections())
    //    {
    foreach (QTcpSocket *temp, m_clientList)
    {
        if (temp->state() == QTcpSocket::ConnectedState)
        {
            temp->write(data);
        }
        else
        {
            m_clientList.removeAll(temp);
            temp->deleteLater();
        }
    }
    //    }
}

void Server::NewClient_cb()
{
    // 循环获取客户端socket
    while (this->hasPendingConnections())
    {
        QTcpSocket *clientTemp = this->nextPendingConnection(); // 拿到当前的socket
        m_clientList.append(clientTemp);                        // 将当前socket添加到列表中（方便操作）
        connect(clientTemp, &QTcpSocket::readyRead, this, &Server::ReadyReadData_cb);
        connect(clientTemp, &QTcpSocket::disconnected, this, &Server::Disconnect_cb); // 连接客户端断开信号
        emit ConnectedSignal(clientTemp);                                             // 发出客户端连接信号
    }
}

void Server::ReadyReadData_cb()
{
    // 拿到发送信号的客户端指针，通过该指针读取数据
    QTcpSocket *curClient = dynamic_cast<QTcpSocket *>(sender());
    emit RecvDataSignal(curClient->readAll());
}

void Server::Disconnect_cb(void)
{

    emit DisconnectedSignal(NULL);
}
